/**
 * 统一API响应格式和错误处理工具类
 */

export interface ApiResponse<T = any> {
  success: boolean;
  message?: string;
  data?: T;
  error?: string;
  code?: string;
  timestamp: string;
}

export interface PaginationMeta {
  current: number; // 改为current以匹配DTO定义
  pageSize: number; // 改为pageSize以匹配DTO定义
  total: number;
  totalPages: number;
  hasNext?: boolean; // 可选字段
  hasPrev?: boolean; // 可选字段
}

export interface PaginatedResponse<T = any> extends ApiResponse<T[]> {
  pagination: PaginationMeta;
}

/**
 * 成功响应
 */
export function successResponse<T = any>(
  data?: T,
  message?: string
): ApiResponse<T> {
  return {
    success: true,
    message,
    data,
    timestamp: new Date().toISOString()
  };
}

/**
 * 分页成功响应
 */
export function paginatedResponse<T = any>(
  items: T[],
  pagination: PaginationMeta,
  message?: string
): PaginatedResponse<T> {
  return {
    success: true,
    message,
    data: items,
    pagination,
    timestamp: new Date().toISOString()
  };
}

/**
 * 错误响应
 */
export function errorResponse(
  message: string,
  error?: string,
  statusCode?: number
): ApiResponse {
  return {
    success: false,
    message,
    error,
    timestamp: new Date().toISOString()
  };
}

/**
 * 验证错误响应
 */
export function validationErrorResponse(
  message: string = '请求参数验证失败',
  error?: string
): ApiResponse {
  return errorResponse(message, error);
}

/**
 * 未找到错误响应
 */
export function notFoundResponse(
  message: string = '资源不存在'
): ApiResponse {
  return errorResponse(message);
}

/**
 * 未授权错误响应
 */
export function unauthorizedResponse(
  message: string = '未授权访问'
): ApiResponse {
  return errorResponse(message);
}

/**
 * 权限不足错误响应
 */
export function forbiddenResponse(
  message: string = '权限不足'
): ApiResponse {
  return errorResponse(message);
}

/**
 * 服务器内部错误响应
 */
export function internalErrorResponse(
  message: string = '服务器内部错误',
  error?: string
): ApiResponse {
  return errorResponse(message, error);
}

/**
 * 创建分页元数据
 */
export function createPaginationMeta(
  current: number,
  pageSize: number,
  total: number
): PaginationMeta {
  const totalPages = Math.ceil(total / pageSize);
  
  return {
    current,
    pageSize,
    total,
    totalPages,
    hasNext: current < totalPages,
    hasPrev: current > 1
  };
}

/**
 * 错误类型枚举
 */
export enum ErrorType {
  VALIDATION = 'VALIDATION',
  NOT_FOUND = 'NOT_FOUND',
  UNAUTHORIZED = 'UNAUTHORIZED',
  FORBIDDEN = 'FORBIDDEN',
  INTERNAL_ERROR = 'INTERNAL_ERROR',
  DUPLICATE = 'DUPLICATE',
  CONFLICT = 'CONFLICT'
}

/**
 * 自定义错误类
 */
export class ApiError extends Error {
  public readonly type: ErrorType;
  public readonly statusCode: number;
  public readonly details?: any;

  constructor(
    type: ErrorType,
    message: string,
    statusCode: number = 500,
    details?: any
  ) {
    super(message);
    this.type = type;
    this.statusCode = statusCode;
    this.details = details;
    this.name = 'ApiError';
  }

  static validation(message: string, details?: any): ApiError {
    return new ApiError(ErrorType.VALIDATION, message, 400, details);
  }

  static notFound(message: string = '资源不存在'): ApiError {
    return new ApiError(ErrorType.NOT_FOUND, message, 404);
  }

  static unauthorized(message: string = '未授权访问'): ApiError {
    return new ApiError(ErrorType.UNAUTHORIZED, message, 401);
  }

  static forbidden(message: string = '权限不足'): ApiError {
    return new ApiError(ErrorType.FORBIDDEN, message, 403);
  }

  static internal(message: string = '服务器内部错误', details?: any): ApiError {
    return new ApiError(ErrorType.INTERNAL_ERROR, message, 500, details);
  }

  static duplicate(message: string = '资源已存在'): ApiError {
    return new ApiError(ErrorType.DUPLICATE, message, 409);
  }

  static conflict(message: string = '操作冲突'): ApiError {
    return new ApiError(ErrorType.CONFLICT, message, 409);
  }
}

/**
 * 错误处理中间件
 */
export function handleApiError(error: any): ApiResponse {
  console.error('API Error:', error);

  if (error instanceof ApiError) {
    return errorResponse(error.message, error.details);
  }

  // 处理数据库错误
  if (error.code === 'SQLITE_CONSTRAINT_UNIQUE') {
    return errorResponse('数据已存在，请检查重复项');
  }

  if (error.code === 'SQLITE_CONSTRAINT_FOREIGNKEY') {
    return errorResponse('关联数据不存在，请检查引用关系');
  }

  // 处理验证错误
  if (error.name === 'ValidationError') {
    return validationErrorResponse(error.message);
  }

  // 默认内部错误
  return internalErrorResponse(
    '服务器内部错误',
    process.env.NODE_ENV === 'development' ? error.message : undefined
  );
}

/**
 * 异步错误处理包装器
 */
export function asyncHandler<T extends any[], R>(
  fn: (...args: T) => Promise<R>
) {
  return async (...args: T): Promise<R> => {
    try {
      return await fn(...args);
    } catch (error) {
      throw error instanceof ApiError ? error : ApiError.internal('操作失败', error);
    }
  };
}

/**
 * 日志记录工具
 */
export class Logger {
  private static formatMessage(level: string, message: string, meta?: any): string {
    const timestamp = new Date().toISOString();
    const metaStr = meta ? ` | ${JSON.stringify(meta)}` : '';
    return `[${timestamp}] [${level.toUpperCase()}] ${message}${metaStr}`;
  }

  static info(message: string, meta?: any): void {
    // console.log(this.formatMessage('info', message, meta));
  }

  static warn(message: string, meta?: any): void {
    console.warn(this.formatMessage('warn', message, meta));
  }

  static error(message: string, meta?: any): void {
    console.error(this.formatMessage('error', message, meta));
  }

  static debug(message: string, meta?: any): void {
    if (process.env.NODE_ENV === 'development') {
      console.debug(this.formatMessage('debug', message, meta));
    }
  }

  static api(method: string, path: string, statusCode: number, duration?: number): void {
    const durationStr = duration ? ` | ${duration}ms` : '';
    this.info(`${method} ${path} - ${statusCode}${durationStr}`);
  }
}